#include <stdio.h>
#include <termios.h>
#include <string.h>
#include <stdlib.h>

#include "armsdkcmdterm.h"
#include "armsdkcli.h"
#include "armsdkcmdregister.h"
#include "armsdkcmdhist.h"
#include "uartglob.h"

INT4 i4charNum = 0;
cmdHistList_t *cmd_node_ptr = NULL;

INT4 adAPISdkCmdInputHandle(CHR *c, CHR *cmdStr, INT4 *cnt)
{
    CHR *pu1cmd = NULL;
    BOOL charmod = FALSE;
    CHR au1cmd[CMD_WORD_LEN] = {0};
    CHR tempcmd[CMD_WORD_LEN] = {0};
    MEMCPY(au1cmd, cmdStr, strlen(cmdStr));

    while (TRUE)
    {
        *c = getchar();
        if (*c != EOF)
        {
            if (i4charNum == 0 && *c == '\x1B')
            {
                i4charNum ++;
                continue;
            }
            else if (i4charNum == 1 && *c == '[')
            {
                i4charNum ++;
                continue;
            }
            else if (i4charNum == 2)
            {
                i4charNum = 0;

                if (*c == 'A')       /* 上键 */
                {
                    printf("\r");
                    printf("\033[K");
                    MEMSET(tempcmd, 0, CMD_WORD_LEN);

                    /* 添加命令到历史列表*/
                    /* 从历史列表中找到上一条命令 */
                    ARM_CMD_PROMPT();
                    pu1cmd = last_cmdHist(&cmd_node_ptr);
                    if (pu1cmd != NULL)
                    {
                        STRCPY(tempcmd, pu1cmd);
                        printf("%s", tempcmd);
                    }
                    charmod = TRUE;

                    continue;
                }
                else if (*c == 'B')  /* 下键 */
                {
                    printf("\r");
                    printf("\033[K");
                    MEMSET(tempcmd, 0, CMD_WORD_LEN);

                    /* 从历史列表中找到下一条命令, 
                     * 最后一条会显示当前输入内容, 没有为空 */
                    ARM_CMD_PROMPT();
                    pu1cmd = next_cmdHist(&cmd_node_ptr);
                    if (pu1cmd != NULL)
                    {
                        STRCPY(tempcmd, pu1cmd);
                        printf("%s", tempcmd);
                        charmod = TRUE;
                    }
                    else
                    {
                        charmod = FALSE;
                        printf("%s", cmdStr);
                    }

                    continue;
                }
#if 0
                else if (*c == 'D')  /* 左键 */
                {
                    printf("left key");
                    continue;
                }
                else if (*c == 'C')  /* 右键 */
                {
                    printf("right key");
                    continue;
                }
#endif
            }
            else
            {
                i4charNum = 0;
            }

            if (*c == 8) /*backspace*/
            {
                printf("\r");
                printf("\033[K");
                ARM_CMD_PROMPT();

                if (charmod == TRUE)
                {
                    if (strlen(tempcmd) > 0)
                    {
                        tempcmd[strlen(tempcmd) - 1] = '\0';
                    }
                    printf("%s", tempcmd);
                }
                else 
                {
                    /*如果输入字符没有删完，输出退格*/
                    if (*cnt >= 1)  /*输入字符没删完*/
                    {
                        (*cnt) --;
                        cmdStr[*cnt] = '\0';
                        au1cmd[*cnt] = '\0';
                    }
                    printf("%s", cmdStr);
                }
                continue;
            }

            /*只有backspace字符显示需要特殊处理*/
            if (*c == 9 || *c == '?')    /* tab键，这里添加命令补全功能*/
            {
                printf("\n");
                /*打印下一个命令可选项*/
                tip_nextWord(au1cmd);
                MEMCPY(au1cmd, cmdStr, *cnt + 1);
                PRINTF("%s", cmdStr);

                continue;
            }
            else if (*c == '\n')    /* 回车 */
            {
                printf("\n");

                if (tempcmd[0] != '\0')
                {
                    /* 更新历史列表 */
                    update_cmdHist(cmd_node_ptr, tempcmd);

                    STRCPY(cmdStr, tempcmd);
                    MEMSET(tempcmd, 0, CMD_WORD_LEN);
                    cmd_node_ptr = NULL;
                }
                else
                {
                    /* 添加命令到历史列表 */
                    add_cmdHist(cmdStr);
                }
                charmod = FALSE;
                break;
            }
            else    /*正常字符*/
            {
                if (charmod == TRUE)
                {
                    tempcmd[strlen(tempcmd)] = *c;
                }
                else
                {
                    cmdStr[*cnt] = *c;
                    au1cmd[*cnt] = *c;
                    (*cnt) ++;
                }
                printf("%c", *c);

                continue;
            }
        }
    }
}

VOID tip_nextWord(CHR *pu1CmdStr)
{
    INT4 i4Inc = 0;
    CHR  *pu1CmdWord[16] = {NULL};
    CHR *pu1CmdListRet = NULL;
    cmdStrList_t *cmdList;
    
    /* split cmd str*/
    pu1CmdWord[i4Inc] = strtok(pu1CmdStr, " ");
    while(pu1CmdWord[i4Inc] != NULL)
    {
        i4Inc ++;
        pu1CmdWord[i4Inc] = strtok(NULL, " ");
    }

    if (pu1CmdWord[0] == NULL)
    {
        PRINTF("\n");
        return;
    }

    for (i4Inc = 0; pu1CmdWord[i4Inc] != NULL; i4Inc ++)
    {
    }
    i4Inc -= 1;

    if (eCurCmdLevel == CMD_LEVEL_ROOT)
    {
        cmdList = &gu1CmdList;
    }
    else if (eCurCmdLevel == CMD_LEVEL_MODULE)
    {
        ARM_CMD_IS_SUBMODULE("uart");
        {
            cmdList = &guartCmdList;
        }
    }

    pu1CmdListRet = research_cmdList(cmdList, pu1CmdWord[i4Inc], i4Inc);
    if (pu1CmdListRet != NULL)
    {
        PRINTF("%s\n", pu1CmdListRet);
    }
    else
    {
        PRINTF("\n");
        return;
    }
}

// 设置终端为非规范模式
void set_unbuffered_input() 
{
    struct termios term;
    tcgetattr(STDIN_FILENO, &term);
    term.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN | OPOST);  // 禁用规范模式和回显
    tcsetattr(STDIN_FILENO, TCSANOW, &term);
}

void reset_terminal_but_sig() 
{
    struct termios term;
    tcgetattr(STDIN_FILENO, &term);
    term.c_lflag |= (ICANON | ECHO | IEXTEN | OPOST);  // 恢复规范模式和回显
    term.c_lflag &= ~ISIG;
    tcsetattr(STDIN_FILENO, TCSANOW, &term);
    system ("stty erase ^H");
}

// 恢复终端设置
void reset_terminal() 
{
    struct termios term;
    tcgetattr(STDIN_FILENO, &term);
    term.c_lflag |= (ICANON | ECHO | ISIG | IEXTEN | OPOST);  // 恢复规范模式和回显
    tcsetattr(STDIN_FILENO, TCSANOW, &term);
}

